package org.liveboardgames.agricola.business;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.liveboardgames.agricola.access.ICardDao;
import org.liveboardgames.agricola.domain.board.BoardTile;
import org.liveboardgames.agricola.domain.card.ActionCard;
import org.liveboardgames.agricola.model.enums.BoardTileTypeEnum;
import org.liveboardgames.agricola.model.enums.GameTypeEnum;

public class BoardTilesServicesImpl implements IBoardTilesService {

  private static final int NUMBER_OF_BOARD_TILES = 30;

  private static final int NUMBER_OF_NON_SEASON_TILES = 16;

  private ICardDao cardDao;

  public void setCardDao(ICardDao cardDao) {
    this.cardDao = cardDao;
  }

  public List<BoardTile> createTiles(int numberOfPlayers, GameTypeEnum gameType) {
    List<BoardTile> tiles = new ArrayList<BoardTile>();

    for (int i = 0; i < NUMBER_OF_BOARD_TILES; i++) {
      BoardTile boardTile = new BoardTile();
      boardTile.setId(i);

      // Indicate the type for the Season tiles, i.e. the
      // tiles that get recovered little by little
      if (i >= NUMBER_OF_NON_SEASON_TILES) {
        boardTile.setType(BoardTileTypeEnum.SEASON);
      }

      tiles.add(boardTile);
    }

    // Retrieve the action cards for the left part of the board
    List<ActionCard> startingActionCards = getStartingActionCards(numberOfPlayers, gameType);
    Collections.shuffle(startingActionCards);
    for (int i = 0; i < startingActionCards.size(); i++) {
      ActionCard actionCard = startingActionCards.get(i);
      BoardTile currentTile = tiles.get(i);
      currentTile.setActionCard(actionCard);
    }

    // Sets up the cards for the static part of the board
    List<ActionCard> staticCards = getStaticActionCards(gameType);
    for (int i = 0; i < staticCards.size(); i++) {
      ActionCard actionCard = staticCards.get(i);
      // The six first tiles are dedicated to the changing cards. The first
      // static tile is the seventh.
      BoardTile currentTile = tiles.get(i + 6);
      currentTile.setActionCard(actionCard);
    }

    return tiles;
  }

  private List<ActionCard> getStaticActionCards(GameTypeEnum gameType) {
    List<ActionCard> actionCards = cardDao.getStaticActionCards(gameType);
    return actionCards;
  }

  private List<ActionCard> getStartingActionCards(int numberOfPlayers, GameTypeEnum gameType) {
    List<ActionCard> actionCards = cardDao.getStartingActionCards(gameType, numberOfPlayers);
    return actionCards;
  }
}
